
<template>
  <div>
    <el-option
      v-for="(item, i) in opt"
      :key="Math.random() + i"
      :label="item.label"
      :value="getValue(item.value)"
      :disabled="isdiabled(item.value)"
    >
    </el-option>
  </div>
</template>

<script>
import { isArray, isFunction, isPlainObject } from 'lodash'
export default {
  props: {
    // value的强制类型转换函数，（Number | String） ,valueType:String
    valueType: {
      type: Function
    },
    // 监听字段，变化时重新拉取字典
    watchField: {
      type: null
    },
    // 字典数据源
    options: {
      type: [Array, Function, Promise],
      default: () => []
    },
    // label字段名
    labelField: {
      type: String,
      require: true
    },
    // value字段名
    valueField: {
      type: String,
      require: true
    },
    disabledItems: {
      type: [Array, Function]
    }
  },
  data () {
    return {
      opt: []
    }
  },
  watch: {
    watchField (val) {
      val !== 'donot' && this.renderData()
    }
  },
  methods: {
    isdiabled (val) {
      if (isArray(this.disabledItems)) {
        return !this.disabledItems.includes(val)
      }

      if (isFunction(this.disabledItems)) {
        return this.disabledItems(val)
      }
    },
    getValue (val) {
      if (isPlainObject(val)) return val
      const tar = (this.valueType || Number)(val)
      if (isNaN(tar)) {
        return val
      } else {
        return tar
      }
    },
    async renderData () {
      let type = Object.prototype.toString.call(this.options)
      switch (type) {
        case '[object Array]':
          this.opt = this.options.map(i => ({
            label: i[this.labelField],
            value: i[this.valueField]
          }))
          break
        case '[object Function]':
          this.opt = (await this.options()).map(i => ({
            label: i[this.labelField],
            value: i[this.valueField]
          }))
          break
        case '[object Promise]':
          this.options.then(res => {
            this.opt = res.map(i => ({
              label: i[this.labelField],
              value: i[this.valueField]
            }))
          })
          break
      }
    }
  },
  mounted () {
    if (this.watchField && this.watchField === 'donot') return
    this.renderData()
  }
}
</script>

<style></style>
